package nessie;

/*
 * the NES stack is an area of its RAM memory(not sure if non RAM stacks exist, but whatever)
 * that is accessed both through pushing and popping the stack, and through
 * instructions that directly access that memory block.
 * that's why this class was created, a kind of pointer to the "actual" stack.
 * strangely enough, this stack doesn't under- or overflow.
 */
public class Stack {

    private Stack() {
    }
    /**Stack Pointer*/
    private static final int STACK_OFFSET = 0x100;

    /**changes the value of the pointer*/
    public static void setSP(byte SP) {
        Registers.SP = SP;
    }

    /**@return the value of the pointer*/
    public static byte getSP() {
        return Registers.SP;
    }

    /**pushes an 8bit value onto the stack*/
    public static void pushSP(byte somethingToPush) {
        Memory.writeByte(STACK_OFFSET + (Registers.SP & 0xFF), somethingToPush);
        --Registers.SP;
    }

    /**pops an 8bit value from the stack*/
    public static byte popSP() {
        ++Registers.SP;
        return Memory.readByte(STACK_OFFSET + (Registers.SP & 0xFF));
    }

    /**
     * pushes a 16bit value onto the stack
     * @see pushSP()
     * @param somethingWideToPush
     */
    public static void pushWideSP(short somethingWideToPush) {
        byte b = (byte) (somethingWideToPush & 0xFF);
        byte a = (byte) ((somethingWideToPush >> 8) & 0xFF);
        pushSP(a);
        pushSP(b);
    }

    /**
     * pops a 16bit value from the stack
     * @see popSP()
     * @return
     */
    public static short popWideSP() {
        int b = popSP() & 0xFF;
        int a = ((popSP() & 0xFF) << 8);

        return (short) (a + b);
    }
}
